﻿using Levfier.GUI.Status;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;

namespace Levfier.GUI.EditorControls
{
    /// <summary>
    /// 画面上に表示するアイコン
    /// </summary>
    [Serializable]
    abstract public class EditorControl : UserControl, IDrawable, IMovable, IPropertyEditor, IStatusCreatable
    {
        /// <summary>
        /// IDの連番
        /// </summary>
        private static int totalId = 0;

        /// <summary>
        /// キャンバス上の座標
        /// コントロールの左上を表す
        /// </summary>
        public Point Position { get; set; }

        /// <summary>
        /// ID
        /// </summary>
        public string Id
        {
            get { return id; }
            set { this.id = value; }
        }

        /// <summary>
        /// ID
        /// </summary>
        private string id;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public EditorControl()
        {
            this.id = "E" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + totalId;
            totalId++;
        }

        /// <summary>
        /// 座標を更新する
        /// </summary>
        public virtual void Update()
        {
            Canvas.SetLeft(this, this.Position.X);
            Canvas.SetTop(this, this.Position.Y);
        }

        /// <summary>
        /// コントロールの中心座標を取得する
        /// </summary>
        /// <returns>コントロールの中心座標</returns>
        public Point GetCenterPosition()
        {
            double centerX = this.Position.X + this.Width / 2.0;
            double centerY = this.Position.Y + this.Height / 2.0;
            return new Point(centerX, centerY);
        }

        /// <summary>
        /// Statsを生成する
        /// </summary>
        /// <returns>Status</returns>
        public virtual ControlStatus GetStatus()
        {
            EditorControlStatus status = new EditorControlStatus();

            //子クラスの持つControlNameを取得して格納
            FieldInfo controlNameInfo = this.GetType().GetFields().Where<FieldInfo>(info => info.Name == "ControlName" && info.IsStatic == true).First<FieldInfo>();

            //ステータスを設定する
            status.Name = controlNameInfo.GetValue(null).ToString();
            status.Id = this.id;
            status.Position = this.Position;

            return status;
        }

        /// <summary>
        /// 選択された時の動作
        /// 末端の子クラスで実装すること
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        abstract public void Select(object sender);

        /// <summary>
        /// 選択解除された時の動作
        /// 末端の子クラスで実装すること
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        abstract public void Unselect(object sender);

        /// <summary>
        /// プロパティを設定する画面を取得する
        /// </summary>
        /// <returns>プロパティを設定する画面</returns>
        abstract public UserControl GetPropertyEditorView();

        /// <summary>
        /// 自分自身を削除する
        /// </summary>
        abstract public IEnumerable<UIElement> Delete();
    }
}
